!function(){
	"use strict";
	function evalStr(str){
		return str===false || typeof(str)=="undefined" ? false : str.toString()
		.replace(/([\d\.]+)vw/, '($1/100*win_width)')
		.replace(/([\d\.]+)vh/, '($1/100*win_height)')
		.replace(/([\d\.]+)mw/, '($1/100*me_width)')
		.replace(/([\d\.]+)mh/, '($1/100*me_height)')
		.replace(/([\d\.]+)rem/, '($1*html_size)')
		.replace(/(\d+)px/, '$1');
	}
	var Scroll = {version: '1.0.0'};
	//对象缓存属性，可以修改，不可配置和枚举
	$.extend(Scroll,{
		can_action: true,
		Listener:[] //绑定事件集
	},{writable:true})
	$.extend(Scroll,{
		on: function(ele, offset, callback, reverse, repeat){
			if(typeof(offset) != 'object') offset = {x: false, y: offset};
		    offset.x = typeof(offset.x)=="undefined" ? false : evalStr(offset.x);
		    offset.y = typeof(offset.y)=="undefined" ? false : evalStr(offset.y);
		    Scroll.Listener.push({
		        ele     : ele,
		        status  : 1,
		        offset  : offset,
		        callback: callback,
		        reverse : !!reverse,
		        repeat  : !!repeat
		    })
		    Scroll.action();
        },
        /**
		 * 移除指定条件的文档滚动事件监听
		 * @param {Object} ele DOM元素必须
		 * @param {Object} offset 匹配偏移量，规则和绑定相同，不传入表示不验证
		 * @param {Object} reverse 是否翻转|false
		 * @param {Object} repeat 是否重复执行|false
		 */
        off: function(ele, offset, reverse, repeat){
		    if(!ele) return;
		    if(typeof(offset) != 'object') offset = {x: false, y: offset};
		    offset.x = typeof(offset.x)=="undefined" ? false : evalStr(offset.x);
		    offset.y = typeof(offset.y)=="undefined" ? false : evalStr(offset.y);
		    for(var i = 0; i < Scroll.Listener.length;){
		        var in_offset = (offset.x === false || offset.x == Scroll.Listener[i].offset.x) && (offset.y === false || offset.y == Scroll.Listener[i].offset.y);
		        var eq_reverse = typeof(reverse)=="undefined" || Scroll.Listener[i].reverse == !!reverse;
		        var eq_repeat = typeof(repeat)=="undefined" || Scroll.Listener[i].repeat == !!repeat;
		        if(Scroll.Listener[i].ele === ele && in_offset && eq_reverse && eq_repeat){
		            Scroll.Listener.splice(i, 1);
		        }else{
		            i++
		        }
		    }
		},
		action: function(){
			if(!Scroll.can_action || !Scroll.Listener.length) return;
		    //浏览器默认回滚，所以延迟执行
		    Scroll.can_action = false;
		    window.requestAnimFrame = (function(){
            	return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(){
	                if(typeof(arguments[0]) == 'function'){
	                    window.setTimeout(arguments[0], 1000 / 60);
	                }
	            };
	        })();
		    requestAnimFrame(function(){
		    	//单位参数
		        var win_height = window.innerHeight;
		        var win_width = window.innerWidth;
		        var html_size = $('html').css('font-size').replace(/(\d)px/, '$1');
		        var Listener = Scroll.Listener;
		
		        for(var i = 0; i < Listener.length; i++){
		            var me_width = Listener[i].ele.offsetWidth;
		            var me_height = Listener[i].ele.offsetHeight;
		            var offset = $.domOffsetScreen(Listener[i].ele);
		            var to_offset = {
		                x: eval(Listener[i].offset.x),
		                y: eval(Listener[i].offset.y)
		            };
		            if(Listener[i].reverse){//翻转
		                var in_offset = (to_offset.x === false || offset.x > to_offset.x) && (to_offset.y === false || offset.y > to_offset.y);
		                if(in_offset){
		                    if(Listener[i].status){
		                        if(!Listener[i].repeat){
		                            Listener[i].status = 0
		                        }
		                        try{
		                            Listener[i].callback.call(Listener[i].ele);
		                        }catch(e){
		                            $.log(e.stack, 'Scroll执行堆栈出错')
		                        }
		                    }
		                }else{
		                    Listener[i].status = 1;
		                }
		            }else{
		                var in_offset = (to_offset.x === false || offset.x < to_offset.x) && (to_offset.y === false || offset.y < to_offset.y);
		                if(in_offset){
		                    if(Listener[i].status){
		                        if(!Listener[i].repeat){
		                            Listener[i].status = 0
		                        }
		                        try{
		                            Listener[i].callback.call(Listener[i].ele);
		                        }catch(e){
		                            $.log(e.stack, 'Scroll执行堆栈出错')
		                        }
		                    }
		                }else{
		                    Listener[i].status = 1;
		                }
		            }
		        }
		        Scroll.can_action = true;
		    })
		}
	})
	document.addEventListener('scroll', Scroll.action, false);
	
    $.fn.extend({
        scrollOn: function(offset, callback, reverse, repeat){
            this.forEach(function(dom){
                Scroll.on(dom, offset, callback, reverse, repeat)
            })
        },
        scrollOff: function(offset, reverse){
            this.forEach(function(dom){
                Scroll.off(dom, offset, reverse)
            })
        }
    })
	//兼容旧版本
	$.extend(Scroll,{addEventListener: Scroll.on, removeEventListener: Scroll.off});
    $.fn.extend({addScrollListener: $.fn.prototype.scrollOn, removeScrollListener: $.fn.prototype.scrollOff})
    
    $.Scroll = Scroll;
}()
